package main

import "fmt"

//结构体指针

/** 数据类型 **/
//值类型
//int,float,bool,string,array,struct

//引用类型
//slice,map,function,pointer

type Person struct {
	name    string
	age     int
	sex     string
	address string
}

func main() {
	//1.结构体是值类型
	p1 := Person{"王二狗", 30, "男", "北京市"}
	fmt.Println(p1)
	fmt.Printf("%p,%T\n", &p1, p1) //0xc000058040,main.Person

	p2 := p1 //值传递，地址变化了
	fmt.Println(p2)
	fmt.Printf("%p,%T\n", &p2, p2) //0xc000058100,main.Person

	p2.name = "李小花"
	fmt.Println(p2)
	fmt.Println(p1)

	//2.定义结构体指针
	var pp1 *Person
	pp1 = &p1
	fmt.Println(pp1)                //&{王二狗 30 男 北京市}
	fmt.Printf("%p,%T\n", pp1, pp1) //0xc000154000,*main.Person
	fmt.Println(*pp1)               //{王二狗 30 男 北京市}

	//(*pp1).name = "李四"，简化
	//修改字段的属性
	pp1.name = "王五"
	fmt.Println(pp1) //&{王五 30 男 北京市}
	fmt.Println(p1)  //{王五 30 男 北京市}

	/**
	 * new()创建的指针，不是nil空指针
	 * 而是指向了新分配的类型的内存空间，里面存储的零值。
	 **/

	//使用内置函数new()，go语言中专门用于创建某种类型的指针的函数
	pp2 := new(Person)
	fmt.Printf("%T\n", pp2) //*main.Person
	fmt.Println(pp2)        //&{ 0  }
	//(*pp2).name
	pp2.name = "Jerry"
	pp2.age = 20
	pp2.sex = "男"
	pp2.address = "上海市"
	fmt.Println(pp2) //&{Jerry 20 男 上海市}

	pp3 := new(int)
	fmt.Println(pp3)  //0xc0000aa0a0
	fmt.Println(*pp3) //0，默认值为空值

	pp4 := new(string)
	fmt.Println(pp4)  //0xc00004c250
	fmt.Println(*pp4) //""

	pp5 := new([]int)
	fmt.Println(pp5)  //&[]
	fmt.Println(*pp5) //[]
}
